﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;

namespace tomenglertde.SetupProject.Model
{
    public class NodeEntity : Entity
    {
        private readonly NodeEntity _parent;
        private readonly ObservableCollection<ValueEntity> _values = new ObservableCollection<ValueEntity>();
        private readonly ObservableCollection<NodeEntity> _children = new ObservableCollection<NodeEntity>();
        private readonly List<Entity> _entities = new List<Entity>();

        public NodeEntity(NodeEntity parent)
        {
            _parent = parent;
            _values.CollectionChanged += any_CollectionChanged;
            _children.CollectionChanged += any_CollectionChanged;
        }

        public NodeEntity Parent
        {
            get
            {
                return _parent;
            }
        }

        void any_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.OldItems != null)
            {
                foreach (var item in e.OldItems)
                {
                    _entities.Remove((Entity)item);
                }
            }

            if (e.NewItems != null)
            {
                foreach (var item in e.NewItems)
                {
                    _entities.Add((Entity)item);
                }
            }
        }

        public IList<ValueEntity> Values
        {
            get
            {
                return _values;
            }
        }

        public IList<NodeEntity> Children
        {
            get
            {
                return _children;
            }
        }

        public IList<Entity> Entities
        {
            get
            {
                return new ReadOnlyCollection<Entity>(_entities);
            }
        }

        public string GetValue(string name)
        {
            var item = Values.Single(v => v.Name == name);
            return item.Value;
        }

        public void SetValue(string name, string value)
        {
            var item = Values.Single(v => v.Name == name);
            item.Value = value;
        }

        public NodeEntity GetChild(string name)
        {
            return Children.Single(item => item.Name == name);
        }

        public override string ToString()
        {
            return "\"" + Name + "\"";
        }

        public NodeEntity Clone(NodeEntity parent)
        {
            var clone = new NodeEntity(parent) { Name = Name };

            foreach (var value in _values)
            {
                clone._values.Add(value.Clone());
            }

            foreach (var child in _children)
            {
                clone._children.Add(child.Clone(clone));
            }

            return clone;
        }
    }
}
